/******************************************************************************/
/* @ All Rights Reserved Copyright (C) 2014 broada,Ltd.                       */
/*                                                                            */
/*  NAME      = informix_common.c                                             */
/*  NOTE      = TDS 请求解析                                                  */
/*  DATE      = 2015/08/26 by zhengxd                                         */
/******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <math.h>
#include <stdint.h>
#include <limits.h>

#include "informix_common.h"
#include "informix_sql_type.h"

#define FRTDS_2_POWER_23  8388608
#define FRTDS_2_POWER_24  16777216
#define FRTDS_2_POWER_52  4503599627370496
#define FRTDS_2_POWER_55  36028797018963968
#define FRTDS_2_POWER_56  72057594037927936

#define DIV(a, b) ((a) / (b) - ((a) % (b) < 0))
#define LEAPS_THRU_END_OF(y) (DIV (y, 4) - DIV (y, 100) + DIV (y, 400))
/* 判断是否是闰年 */
#define ISLEAP(year) ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
/* 一年月份分布 */
static const unsigned short int frtds_mon_yday[2][13] =
{
    /* Normal years.  */
    { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
    /* Leap years.  */
    { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
};

/*******************************************************************************
*  FUNC     :  将天数转换为年月日
*  ARGS     :  i_days(天数)
*           :  p_ui_year(年)
*           :  p_ui_month(月)
*           :  p_ui_day(日)
*  RTN      :  void
*  NOTE     :
*******************************************************************************/
static void __informix_days_fromat(int i_days
                                  , unsigned int *p_ui_year
                                  , unsigned int *p_ui_month
                                  , unsigned int *p_ui_day)
{
    unsigned int ui_year_guess = 0;
    unsigned int ui_year = 1900;
    unsigned int ui_loop = 0;
    const unsigned short int *p_us_mon_yday;

    while (i_days < 0 || i_days >= (ISLEAP(ui_year) ? 366 : 365))
    {
        /* Guess a corrected year, assuming 365 days per year.  */
        ui_year_guess = ui_year + i_days / 365 - (i_days % 365 < 0);

        /* Adjust DAYS and Y to match the guessed year.  */
        i_days -= ((ui_year_guess - ui_year) * 365
                    + LEAPS_THRU_END_OF(ui_year_guess - 1)
                    - LEAPS_THRU_END_OF(ui_year - 1));
        ui_year = ui_year_guess;
    }

    p_us_mon_yday = frtds_mon_yday[ISLEAP(ui_year)];
    for (ui_loop = 11; i_days < (long int)p_us_mon_yday[ui_loop]; --ui_loop)
    {
        continue;
    }

    *p_ui_day = i_days - p_us_mon_yday[ui_loop] + 1;
    *p_ui_month = ui_loop + 1;
    *p_ui_year = ui_year;
    return;
}

/*******************************************************************************
*  FUNC     :  binary转单精度浮点型
*  ARGS     :  p_buffer(入力数据)
*           :  i_float_type(浮点数据类型)
*           :  pp_value(出力数据)
*  RTN      :  APM_L7_ANALYZE_FAIL      (FAIL)
*              APM_L7_ANALYZE_SUCC      (SUCC)
*  NOTE     :  p_binary_str长度必须是4
*******************************************************************************/
static int __informix_binary_to_float(char *p_buff
                                     , int i_float_type
                                     , char **pp_value)
{
    float f_sign_bit = 0;
    float f_exponent = 0;
    float f_fraction = 0;
    float f_power = 0;
    float f_value = 0;
    uint32_t u32_byte1 = 0;
    uint32_t u32_byte2 = 0;
    uint32_t u32_byte3 = 0;
    uint32_t u32_byte4 = 0;
    char *p_value = NULL;

    switch (i_float_type)
    {
        case INFORMIX_FLT_IEEE_HI:
            u32_byte1 = p_buff[3];
            u32_byte2 = p_buff[2];
            u32_byte3 = p_buff[1];
            u32_byte4 = p_buff[0];
            /* 取得符号位 */
            f_sign_bit = (u32_byte1 & 0x80) >> 7;
            /* 取得阶码 */
            f_exponent = ((u32_byte1 & 0x7F) << 1) + ((u32_byte2 & 0x80) >> 7);
            f_power = powf(2, f_exponent - 127);
            /* 取得尾数 */
            f_fraction = ((u32_byte2 & 0x7F) << 16) + (u32_byte3 << 8) + u32_byte4;
            f_fraction /= FRTDS_2_POWER_23;
            f_fraction += 1.0;
            break;

        case INFORMIX_FLT_VAXD:
            u32_byte1 = p_buff[2];
            u32_byte2 = p_buff[3];
            u32_byte3 = p_buff[0];
            u32_byte4 = p_buff[1];
            /* 取得符号位 */
            f_sign_bit = (u32_byte1 & 0x80) >> 7;
            /* 取得阶码 */
            f_exponent = ((u32_byte1 & 0x7F) << 1) + ((u32_byte2 & 0x80) >> 7);
            f_power = powf(2, f_exponent - 127);
            /* 取得尾数 */
            f_fraction = ((u32_byte2 & 0x7F) << 16) + (u32_byte3 << 8) + u32_byte4;
            f_fraction /= FRTDS_2_POWER_24;
            f_fraction += 0.5;
            break;

        case INFORMIX_FLT_IEEE_LO:
            u32_byte1 = p_buff[0];
            u32_byte2 = p_buff[1];
            u32_byte3 = p_buff[2];
            u32_byte4 = p_buff[3];
            /* 取得符号位 */
            f_sign_bit = (u32_byte1 & 0x80) >> 7;
            /* 取得阶码 */
            f_exponent = ((u32_byte1 & 0x7F) << 1) + ((u32_byte2 & 0x80) >> 7);
            f_power = powf(2, f_exponent - 127);
            /* 取得尾数 */
            f_fraction = ((u32_byte2 & 0x7F) << 16) + (u32_byte3 << 8) + u32_byte4;
            f_fraction /= FRTDS_2_POWER_23;
            f_fraction += 1.0;
            break;

        case INFORMIX_FLT_ND5000:
            u32_byte1 = p_buff[0];
            u32_byte2 = p_buff[1];
            u32_byte3 = p_buff[2];
            u32_byte4 = p_buff[3];
            /* 取得符号位 */
            f_sign_bit = (u32_byte1 & 0x80) >> 7;
            /* 取得阶码 */
            f_exponent = u32_byte1 & 0x7F;
            f_power = powf(16, f_exponent - 64);
            /* 取得尾数 */
            f_fraction = (u32_byte2 << 16) + (u32_byte3 << 8) + u32_byte4;
            f_fraction /= FRTDS_2_POWER_24;
            break;

        default:
            return APM_L7_ANALYZE_FAIL;
    }

    f_value = powf(-1, f_sign_bit) * f_power * f_fraction;
    /* 申请足够长的内存 */
    p_value = (char *)frmalloc(128);
    if (p_value == NULL)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    snprintf(p_value, 128, "%f", f_value);
    *pp_value = p_value;
    return APM_L7_ANALYZE_SUCC;
}

/*******************************************************************************
*  FUNC     :  binary转双精度浮点型
*  ARGS     :  p_buffer(入力数据)
*           :  i_float_type(浮点数据类型)
*           :  pp_value(出力数据)
*  RTN      :  APM_L7_ANALYZE_FAIL      (FAIL)
*              APM_L7_ANALYZE_SUCC      (SUCC)
*  NOTE     :  p_binary_str长度必须是8
*******************************************************************************/
static int __informix_binary_to_double(char *p_buff
                                      , int i_float_type
                                      , char **pp_value)
{
    double d_sign_bit = 0;
    double d_exponent = 0;
    double d_fraction = 0;
    double d_power = 0;
    double d_value = 0;
    uint64_t u64_byte1 = 0;
    uint64_t u64_byte2 = 0;
    uint64_t u64_byte3 = 0;
    uint64_t u64_byte4 = 0;
    uint64_t u64_byte5 = 0;
    uint64_t u64_byte6 = 0;
    uint64_t u64_byte7 = 0;
    uint64_t u64_byte8 = 0;
    char *p_value = NULL;

    switch (i_float_type)
    {
        case FRTDS_FLT_IEEE_HI:
            u64_byte1 = p_buff[7];
            u64_byte2 = p_buff[6];
            u64_byte3 = p_buff[5];
            u64_byte4 = p_buff[4];
            u64_byte5 = p_buff[3];
            u64_byte6 = p_buff[2];
            u64_byte7 = p_buff[1];
            u64_byte8 = p_buff[0];
            /* 取得符号位 */
            d_sign_bit = (u64_byte1 & 0x80) >> 7;
            /* 取得阶码 */
            d_exponent = ((u64_byte1 & 0x7F) << 4) + ((u64_byte2 & 0xF0) >> 4);
            d_power = pow(2, d_exponent - 1023);
            /* 取得尾数 */
            d_fraction = ((u64_byte2 & 0x0F) << 48)
                         + (u64_byte3 << 40)
                         + (u64_byte4 << 32)
                         + (u64_byte5 << 24)
                         + (u64_byte6 << 16)
                         + (u64_byte7 << 8)
                         + u64_byte8;
            d_fraction /= FRTDS_2_POWER_52;
            d_fraction += 1.0;
            break;

        case FRTDS_FLT_VAXD:
            u64_byte1 = p_buff[2];
            u64_byte2 = p_buff[3];
            u64_byte3 = p_buff[0];
            u64_byte4 = p_buff[1];
            u64_byte5 = p_buff[6];
            u64_byte6 = p_buff[7];
            u64_byte7 = p_buff[4];
            u64_byte8 = p_buff[5];
            /* 取得符号位 */
            d_sign_bit = (u64_byte1 & 0x80) >> 7;
            /* 取得阶码 */
            d_exponent = ((u64_byte1 & 0x7F) << 1) + ((u64_byte2 & 0x80) >> 7);
            d_power = pow(2, d_exponent - 127);
            /* 取得尾数 */
            d_fraction = ((u64_byte2 & 0x7F) << 48)
                         + (u64_byte3 << 40)
                         + (u64_byte4 << 32)
                         + (u64_byte5 << 24)
                         + (u64_byte6 << 16)
                         + (u64_byte7 << 8)
                         + u64_byte8;
            d_fraction /= FRTDS_2_POWER_55;
            d_fraction += 0.5;
            break;

        case FRTDS_FLT_IEEE_LO:
            u64_byte1 = p_buff[0];
            u64_byte2 = p_buff[1];
            u64_byte3 = p_buff[2];
            u64_byte4 = p_buff[3];
            u64_byte5 = p_buff[4];
            u64_byte6 = p_buff[5];
            u64_byte7 = p_buff[6];
            u64_byte8 = p_buff[7];
            /* 取得符号位 */
            d_sign_bit = (u64_byte1 & 0x80) >> 7;
            /* 取得阶码 */
            d_exponent = ((u64_byte1 & 0x7F) << 4) + ((u64_byte2 & 0xF0) >> 4);
            d_power = pow(2, d_exponent - 1023);
            /* 取得尾数 */
            d_fraction = ((u64_byte2 & 0x0F) << 48)
                         + (u64_byte3 << 40)
                         + (u64_byte4 << 32)
                         + (u64_byte5 << 24)
                         + (u64_byte6 << 16)
                         + (u64_byte7 << 8)
                         + u64_byte8;
            d_fraction /= FRTDS_2_POWER_52;
            d_fraction += 1.0;
            break;

        case FRTDS_FLT_ND5000:
            u64_byte1 = p_buff[0];
            u64_byte2 = p_buff[1];
            u64_byte3 = p_buff[2];
            u64_byte4 = p_buff[3];
            u64_byte5 = p_buff[4];
            u64_byte6 = p_buff[5];
            u64_byte7 = p_buff[6];
            u64_byte8 = p_buff[7];
            /* 取得符号位 */
            d_sign_bit = (u64_byte1 & 0x80) >> 7;
            /* 取得阶码 */
            d_exponent = u64_byte1 & 0x7F;
            d_power = pow(16, d_exponent - 64);
            /* 取得尾数 */
            d_fraction = (u64_byte2 << 48)
                        + (u64_byte3 << 40)
                        + (u64_byte4 << 32)
                        + (u64_byte5 << 24)
                        + (u64_byte6 << 16)
                        + (u64_byte7 << 8)
                        + u64_byte8;
            d_fraction /= FRTDS_2_POWER_56;
            break;

        default:
            return APM_L7_ANALYZE_FAIL;
    }

    d_value = pow(-1, d_sign_bit) * d_power * d_fraction;
    /* 申请足够长的内存 */
    p_value = (char *)frmalloc(128);
    if (p_value == NULL)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    snprintf(p_value, 128, "%f", d_value);
    *pp_value = p_value;
    return APM_L7_ANALYZE_SUCC;
}

/*******************************************************************************
*  FUNC     :  解析boolean
*  ARGS     :  p_st_data(入力bytebuff)
*           :  i_null_flg(是否是NULL)
*           :  pp_st_value(出力数据)
*  RTN      :  APM_L7_ANALYZE_FAIL      (FAIL)
*              APM_L7_ANALYZE_TODO      (NEED MORE DATA)
*              APM_L7_ANALYZE_SUCC      (SUCC)
*  NOTE     :  p_st_data肯定不为NULL
*******************************************************************************/
int informix_convert_to_boolean(Frbyte_Packet *p_st_data
                               , int i_null_flg
                               , Frdata_field **pp_st_value)
{
    int i_ret = 0;
    uint8_t u8_null_flg = 0;
    uint8_t u8_boolean_value = 0;
    char *p_boolean = NULL;

    if (i_null_flg != 0)
    {
        i_ret = frtds_create_param(NULL, FRBOOLEAN, pp_st_value);
        return i_ret;
    }
    /* 数据长度不足 */
    if (bytebuff_remaining(p_st_data) < 6)
    {
        return APM_L7_ANALYZE_TODO;
    }
    bytebuff_get_char(p_st_data, &u8_null_flg);
    if (u8_null_flg == 1)
    {
        /* 跳过4byte */
        bytebuff_skip(p_st_data, 4);
        i_ret = frtds_create_param(NULL, FRBOOLEAN, pp_st_value);
        if (i_ret != APM_L7_ANALYZE_SUCC)
        {
            return APM_L7_ANALYZE_FAIL;
        }
    }
    else
    {
        /* 跳过4byte */
        bytebuff_skip(p_st_data, 3);
        bytebuff_get_char(p_st_data, &u8_boolean_value);
        if (u8_boolean_value)
        {
            p_boolean = frstrdup("1");
        }
        else
        {
            p_boolean = frstrdup("0");
        }
        i_ret = frtds_create_param(p_boolean, FRBOOLEAN, pp_st_value);
        if (i_ret != APM_L7_ANALYZE_SUCC)
        {
            frfree(p_boolean);
            return APM_L7_ANALYZE_FAIL;
        }
        bytebuff_skip(p_st_data, 1);
    }

    return APM_L7_ANALYZE_SUCC;
}

/*******************************************************************************
*  FUNC     :  解析整型
*  ARGS     :  p_st_data(入力bytebuff)
*           :  i_null_flg(是否是NULL)
*           :  ui_int_len(表示int型所占据的字节数)
*           :  i_unsigned_flg(是否是unsigned的标识)
*           :  pp_st_value(出力数据)
*  RTN      :  APM_L7_ANALYZE_FAIL      (FAIL)
*              APM_L7_ANALYZE_TODO      (NEED MORE DATA)
*              APM_L7_ANALYZE_SUCC      (SUCC)
*  NOTE     :  p_st_data肯定不为NULL
*******************************************************************************/
int informix_convert_to_int(Frbyte_Packet *p_st_data
                            , int i_null_flg
                            , unsigned int ui_int_len
                            , int i_unsigned_flg
                            , Frdata_field **pp_st_value)
{
    int i_ret = 0;
    uint8_t u8_int_value = 0;
    char c_int_value = 0;
    uint16_t u16_int_value = 0;
    short s_int_value = 0;
    uint32_t u32_int_value = 0;
    int i_int_value = 0;
    uint64_t u64_int_value = 0;
    long long ll_int_value = 0;
    int i_data_type = 0;
    char *p_int_value = NULL;

    /* 是否为NULL */
    if (i_null_flg != 0)
    {
        i_ret = frtds_create_param(NULL, FRINT, pp_st_value);
        return i_ret;
    }
    /* 数据长度不足 */
    if (ui_int_len > (unsigned int)bytebuff_remaining(p_st_data))
    {
        return APM_L7_ANALYZE_TODO;
    }

    /* 32位足够存下整形数据 */
    p_int_value = (char *)frmalloc(32);
    if (p_int_value == NULL)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    memset(p_int_value, 0x0, 32);

    /* 根据数值所占据的长度来解析数据 */
    switch (ui_int_len)
    {
        case 1: /* BYTE型 */
            i_data_type = FRCHAR;
            bytebuff_get_char(p_st_data, &u8_int_value);
            /* 无符号char */
            if (i_unsigned_flg == FR_YES)
            {
                snprintf(p_int_value, 32, "%u", u8_int_value);
            }
            else
            {
                c_int_value = (char)u8_int_value;
                snprintf(p_int_value, 32, "%d", c_int_value);
            }
            break;

        case 2: /* SHORT型 */
            i_data_type = FRSHORT;
            i_ret = bytebuff_get_short(p_st_data, 2, &u16_int_value, BYTE_BIG_ENDIAN);
            if (i_ret != FR_SUCC)
            {
                frfree(p_int_value);
                return APM_L7_ANALYZE_FAIL;
            }
            /* 无符号short */
            if (i_unsigned_flg == FR_YES)
            {
                snprintf(p_int_value, 32, "%u", u16_int_value);
            }
            else
            {
                s_int_value = (short)u16_int_value;
                snprintf(p_int_value, 32, "%d", s_int_value);
            }
            break;

        case 4: /* INT型 */
            i_data_type = FRINT;
            i_ret = bytebuff_get_int(p_st_data, 4, &u32_int_value, BYTE_BIG_ENDIAN);
            if (i_ret != FR_SUCC)
            {
                frfree(p_int_value);
                return APM_L7_ANALYZE_FAIL;
            }
            /* 无符号int */
            if (i_unsigned_flg == FR_YES)
            {
                snprintf(p_int_value, 32, "%u", u32_int_value);
            }
            else
            {
                i_int_value = (int)u32_int_value;
                snprintf(p_int_value, 32, "%d", i_int_value);
            }
            break;

        case 8: /* LONG型 */
            i_data_type = FRLONG;
            i_ret = bytebuff_get_long(p_st_data, 8, &u64_int_value, BYTE_BIG_ENDIAN);
            if (i_ret != FR_SUCC)
            {
                frfree(p_int_value);
                return APM_L7_ANALYZE_FAIL;
            }
            /* 无符号long */
            if (i_unsigned_flg == FR_YES)
            {
                snprintf(p_int_value, 32, PRI64U, u64_int_value);
            }
            else
            {
                ll_int_value = (long long)u64_int_value;
                snprintf(p_int_value, 32, "%lld", ll_int_value);
            }
            break;

        default:
            frfree(p_int_value);
            return APM_L7_ANALYZE_FAIL;
    }

    /* 做成Frdata_field */
    i_ret = frtds_create_param(p_int_value, i_data_type, pp_st_value);
    if (i_ret != APM_L7_ANALYZE_SUCC)
    {
        frfree(p_int_value);
        return APM_L7_ANALYZE_FAIL;
    }
    return APM_L7_ANALYZE_SUCC;
}

/*******************************************************************************
*  FUNC     :  解析浮点型数据
*  ARGS     :  p_st_data(入力bytebuff)
*           :  i_null_flg(是否是NULL)
*           :  ui_float_len(表示float所占据的字节数)
*           :  i_float_type(浮点数类型)
*           :  pp_st_value(出力数据)
*  RTN      :  APM_L7_ANALYZE_FAIL      (FAIL)
*              APM_L7_ANALYZE_TODO      (NEED MORE DATA)
*              APM_L7_ANALYZE_SUCC      (SUCC)
*  NOTE     :  p_st_data肯定不为NULL
*******************************************************************************/
int informix_convert_to_float(Frbyte_Packet *p_st_data
                             , int i_null_flg
                             , unsigned int ui_float_len
                             , int i_float_type
                             , Frdata_field **pp_st_value)
{
    int i_ret = FR_SUCC;
    char arr_buff[8 + 1] = {0};
    char *p_float = NULL;

    /* 是否为NULL */
    if (i_null_flg != 0)
    {
        i_ret = frtds_create_param(NULL, FRFLOAT, pp_st_value);
        return i_ret;
    }
    /* 数据长度不足 */
    if (ui_float_len > (unsigned int)bytebuff_remaining(p_st_data))
    {
        return APM_L7_ANALYZE_TODO;
    }

    if (ui_float_len == 4)
    {
        i_ret = bytebuff_get_bytes(p_st_data, arr_buff, 4);
        if (i_ret != FR_SUCC)
        {
            return APM_L7_ANALYZE_FAIL;
        }
        /* binary转float */
        i_ret = __informix_binary_to_float(arr_buff, i_float_type, &p_float);
        if (i_ret != APM_L7_ANALYZE_SUCC)
        {
            return APM_L7_ANALYZE_FAIL;
        }
        /* 创建参数节点 */
        i_ret = frtds_create_param(p_float, FRFLOAT, pp_st_value);
        if (i_ret != APM_L7_ANALYZE_SUCC)
        {
            frfree(p_float);
            return APM_L7_ANALYZE_FAIL;
        }
    }
    else if (ui_float_len == 8)
    {
        i_ret = bytebuff_get_bytes(p_st_data, arr_buff, 8);
        if (i_ret != FR_SUCC)
        {
            return APM_L7_ANALYZE_FAIL;
        }
        /* binary转double */
        i_ret = __informix_binary_to_double(arr_buff, i_float_type, &p_float);
        if (i_ret != APM_L7_ANALYZE_SUCC)
        {
            return APM_L7_ANALYZE_FAIL;
        }
        /* 创建参数节点 */
        i_ret = frtds_create_param(p_float, FRDOUBLE, pp_st_value);
        if (i_ret != APM_L7_ANALYZE_SUCC)
        {
            frfree(p_float);
            return APM_L7_ANALYZE_FAIL;
        }
    }
    else
    {
        return APM_L7_ANALYZE_FAIL;
    }

    return APM_L7_ANALYZE_SUCC;
}

/*******************************************************************************
*  FUNC     :  解析varchar
*  ARGS     :  p_st_data(入力bytebuff)
*           :  i_null_flg(是否是NULL)
*           :  ui_len_bytes(长度位占据的byte数)
*           :  pp_st_value(出力数据)
*  RTN      :  APM_L7_ANALYZE_FAIL      (FAIL)
*              APM_L7_ANALYZE_TODO      (NEED MORE DATA)
*              APM_L7_ANALYZE_SUCC      (SUCC)
*  NOTE     :  p_st_data肯定不为NULL，ui_byte_len为1或者2或者4
*******************************************************************************/
int informix_convert_to_str(Frbyte_Packet *p_st_data
                           , int i_null_flg
                           , unsigned int ui_len_bytes
                           , Frdata_field **pp_st_value)
{
    int i_ret = FR_SUCC;
    uint8_t u8_bytes_len = 0;
    uint16_t u16_bytes_len = 0;
    uint32_t u32_bytes_len = 0;
    uint64_t u64_bytes_len = 0;
    unsigned int ui_bytes_len = 0;
    char *p_output = NULL;

    /* 是否为NULL */
    if (i_null_flg != 0)
    {
        i_ret = frtds_create_param(NULL, FRSTRING, pp_st_value);
        return i_ret;
    }
    /* 基本格式check */
    if (ui_len_bytes > (unsigned int)bytebuff_remaining(p_st_data))
    {
         return APM_L7_ANALYZE_TODO;
    }
    switch (ui_len_bytes)
    {
        case 1:
            /* 取得长度位,并跳过 */
            bytebuff_get_char(p_st_data, &u8_bytes_len);
            ui_bytes_len = u8_bytes_len;
            break;

        case 2:
            i_ret = bytebuff_get_short(p_st_data, 2, &u16_bytes_len, BYTE_BIG_ENDIAN);
            if (i_ret != FR_SUCC)
            {
                return APM_L7_ANALYZE_FAIL;
            }
            ui_bytes_len = u16_bytes_len;
            break;

        case 4:
            i_ret = bytebuff_get_int(p_st_data, 4, &u32_bytes_len, BYTE_BIG_ENDIAN);
            if (i_ret != FR_SUCC)
            {
                return APM_L7_ANALYZE_FAIL;
            }
            ui_bytes_len = u32_bytes_len;
            break;

        case 8:
            i_ret = bytebuff_get_long(p_st_data, 8, &u64_bytes_len, BYTE_BIG_ENDIAN);
            if (i_ret != FR_SUCC)
            {
                return APM_L7_ANALYZE_FAIL;
            }
            ui_bytes_len = (unsigned int)u64_bytes_len;
            break;

        default:
            return APM_L7_ANALYZE_FAIL;
    }

    /* 基本格式check */
    if (ui_bytes_len > (unsigned int)bytebuff_remaining(p_st_data))
    {
         return APM_L7_ANALYZE_TODO;
    }

    /* 取得varchar */
    if (ui_bytes_len)
    {
        i_ret = informix_read_padded(p_st_data, ui_bytes_len
                                    , &p_output, &ui_bytes_len);
        if (i_ret != APM_L7_ANALYZE_SUCC)
        {
            return APM_L7_ANALYZE_FAIL;
        }
        i_ret = frtds_create_param(p_output, FRSTRING, pp_st_value);
        if (i_ret != APM_L7_ANALYZE_SUCC)
        {
            frfree(p_output);
            return APM_L7_ANALYZE_FAIL;
        }
    }
    else
    {
        i_ret = frtds_create_param(NULL, FRSTRING, pp_st_value);
        if (i_ret != APM_L7_ANALYZE_SUCC)
        {
            return APM_L7_ANALYZE_FAIL;
        }
    }

    return APM_L7_ANALYZE_SUCC;
}

/*******************************************************************************
*  FUNC     :  解析date
*  ARGS     :  p_st_data(入力bytebuff)
*           :  i_null_flg(是否是NULL)
*           :  pp_st_value(出力数据)
*  RTN      :  APM_L7_ANALYZE_FAIL      (FAIL)
*              APM_L7_ANALYZE_TODO      (NEED MORE DATA)
*              APM_L7_ANALYZE_SUCC      (SUCC)
*  NOTE     :  p_st_data肯定不为NULL
*******************************************************************************/
int informix_convert_to_date(Frbyte_Packet *p_st_data
                            , int i_null_flg
                            , Frdata_field **pp_st_value)
{
    int i_ret = FR_SUCC;
    unsigned int ui_year = 1970;
    unsigned int ui_month = 1;
    unsigned int ui_day = 1;
    uint32_t u32_days = 0;
    int i_days = 0;
    char *p_date = NULL;

    /* 是否为NULL */
    if (i_null_flg != 0)
    {
        i_ret = frtds_create_param(NULL, FRTIME, pp_st_value);
        return i_ret;
    }
    /* 数据长度不足 */
    if (bytebuff_remaining(p_st_data) < 4)
    {
        return APM_L7_ANALYZE_TODO;
    }

    /*
    *  IN INFORMIX: date is represented as one 4-byte signed integer that
    *  represents the number of days since January 1, year 1.
    */
    i_ret = bytebuff_get_int(p_st_data, 4, &u32_days, BYTE_BIG_ENDIAN);
    if (i_ret != FR_SUCC)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    /* 设置取得的时间 */
    if (u32_days != 0xFFFFFFFF) /* 根据java反编译 */
    {
        i_days = u32_days;
        /* 将天数转换为年月日 */
        __informix_days_fromat(i_days, &ui_year, &ui_month, &ui_day);
    }
    /* 日期格式YYYY-MM-DD*/
    p_date = (char *)frmalloc(10 + 1);
    if (p_date == NULL)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    snprintf(p_date, 11, "%04d-%02d-%02d",ui_year, ui_month, ui_day);

    /* 创建参数节点 */
    i_ret = frtds_create_param(p_date, FRTIME, pp_st_value);
    if (i_ret != APM_L7_ANALYZE_SUCC)
    {
        frfree(p_date);
        return APM_L7_ANALYZE_FAIL;
    }
    return APM_L7_ANALYZE_SUCC;
}

/*******************************************************************************
*  FUNC     :  解析date
*  ARGS     :  p_st_data(入力bytebuff)
*           :  i_null_flg(是否是NULL)
*           :  pp_st_value(出力数据)
*  RTN      :  APM_L7_ANALYZE_FAIL      (FAIL)
*              APM_L7_ANALYZE_TODO      (NEED MORE DATA)
*              APM_L7_ANALYZE_SUCC      (SUCC)
*  NOTE     :  p_st_data肯定不为NULL
*******************************************************************************/
int informix_convert_to_datetime(Frbyte_Packet *p_st_data
                                 , int i_null_flg
                                 , Frdata_field **pp_st_value)
{
    int i_ret = FR_SUCC;
    unsigned int ui_size = 0;
    uint16_t u16_len = 0;
    char *p_date = NULL;
    char *p_value = NULL;

    /* 是否为NULL */
    if (i_null_flg != 0)
    {
        i_ret = frtds_create_param(NULL, FRTIME, pp_st_value);
        return i_ret;
    }
    /* 数据长度不足 */
    if (bytebuff_remaining(p_st_data) < 2)
    {
        return APM_L7_ANALYZE_TODO;
    }
    /* 取得时间数据长度 */
    i_ret = bytebuff_get_short(p_st_data, 2, &u16_len, BYTE_BIG_ENDIAN);
    if (i_ret != FR_SUCC || u16_len < 8)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    /* 取得数据 */
    i_ret = informix_read_padded(p_st_data, u16_len, &p_date, &ui_size);
    if (i_ret != APM_L7_ANALYZE_SUCC)
    {
        return i_ret;
    }

    /* 分配足够内存,时间格式YYYY-MM-DDThh:mm:ss.xxZ (例2014-11-04T12:12:00.00Z) */
    p_value = (char *)frmalloc(23 + 1);
    if (p_value == NULL)
    {
        frfree(p_date);
        return APM_L7_ANALYZE_FAIL;
    }
    snprintf(p_value, 24, "%04d-%02d-%02dT%02d:%02d:%02d.%02dZ"
            , 1900 + p_date[2], p_date[3], p_date[4], p_date[5]
            , p_date[6], p_date[7], p_date[8]);
    frfree(p_date);
    i_ret = frtds_create_param(p_value, FRTIME, pp_st_value);
    if (i_ret != APM_L7_ANALYZE_SUCC)
    {
        frfree(p_value);
        return APM_L7_ANALYZE_FAIL;
    }

    return APM_L7_ANALYZE_SUCC;
}

/*******************************************************************************
*  FUNC     :  解析informix的decimal类型
*  ARGS     :  p_st_data(入力bytebuff)
*           :  i_null_flg(是否是NULL)
*           :  pp_st_value(出力数据)
*  RTN      :  APM_L7_ANALYZE_FAIL      (FAIL)
*              APM_L7_ANALYZE_TODO      (NEED MORE DATA)
*              APM_L7_ANALYZE_SUCC      (SUCC)
*  NOTE     :  p_st_data肯定不为NULL
*******************************************************************************/
int informix_convert_to_decimal(Frbyte_Packet *p_st_data
                                , int i_null_flg
                                , Frdata_field **pp_st_value)
{
    uint16_t u16_dec_len = 0;
    int i_ret = FR_SUCC;
    int i_dec_type = 0;
    int i_dec_scale = 0;
    int i_loop = 1;
    unsigned int ui_size = 0;
    unsigned int ui_len_tmp = 0;
    int i_tmp = 99;
    char *p_dec_data = NULL;
    char *p_value = NULL;
    char *p_value_tmp = NULL;

    /* 是否为NULL */
    if (i_null_flg != 0)
    {
        i_ret = frtds_create_param(NULL, FRSTRING, pp_st_value);
        return i_ret;
    }
    if (bytebuff_remaining(p_st_data) < 2)
    {
        return APM_L7_ANALYZE_TODO;
    }
    /* 取得decimal数据长度 */
    i_ret = bytebuff_get_short(p_st_data, 2, &u16_dec_len, BYTE_BIG_ENDIAN);
    if (i_ret != FR_SUCC || u16_dec_len < 2)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    /* 取得decimal数据 */
    i_ret = informix_read_padded(p_st_data, u16_dec_len, &p_dec_data, &ui_size);
    if (i_ret != APM_L7_ANALYZE_SUCC)
    {
        return i_ret;
    }
    i_dec_type = (*p_dec_data) & 0xF0;
    i_dec_scale = (*p_dec_data) & 0x0F;

    /* 解析 */
    switch (i_dec_type)
    {
        /* 正数 */
        case 0xC0:
            /* 申请足够长的内存 */
            ui_len_tmp = (ui_size + 2) * 2;
            p_value = (char *)frmalloc(ui_len_tmp);
            if (p_value == NULL)
            {
                frfree(p_dec_data);
                return APM_L7_ANALYZE_FAIL;
            }
            p_value_tmp = p_value;
            for (i_loop = 1; i_loop < u16_dec_len; i_loop++)
            {
                if (i_loop == i_dec_scale + 1)
                {
                    if (i_loop == 1)
                    {
                        snprintf(p_value_tmp, ui_len_tmp, "0.%02d"
                                , p_dec_data[i_loop]);
                        p_value_tmp += 4;
                        ui_len_tmp -= 4;
                    }
                    else
                    {
                        snprintf(p_value_tmp, ui_len_tmp, ".%02d"
                                , p_dec_data[i_loop]);
                        p_value_tmp += 3;
                        ui_len_tmp -= 3;
                    }
                }
                else
                {
                    if (i_loop == 1)
                    {
                        snprintf(p_value_tmp, ui_len_tmp, "%d", p_dec_data[i_loop]);
                        p_value_tmp += strlen(p_value_tmp);
                        ui_len_tmp -= strlen(p_value_tmp);
                    }
                    else
                    {
                        snprintf(p_value_tmp, ui_len_tmp, "%02d", p_dec_data[i_loop]);
                        p_value_tmp += 2;
                        ui_len_tmp -= 2;
                    }
                }
            }
            break;

       /* 正数 */
       case 0xB0:
            i_dec_scale = 16 - i_dec_scale;
            /* 申请足够长的内存 */
            ui_len_tmp = (ui_size + i_dec_scale + 4) * 2;
            p_value = (char *)frmalloc(ui_len_tmp);
            if (p_value == NULL)
            {
                frfree(p_dec_data);
                return APM_L7_ANALYZE_FAIL;
            }
            p_value_tmp = p_value;
            snprintf(p_value_tmp, ui_len_tmp, "0.");
            p_value_tmp += 2;
            ui_len_tmp -= 2;
            while (i_dec_scale--)
            {
                snprintf(p_value_tmp, ui_len_tmp, "00");
                p_value_tmp += 2;
                ui_len_tmp -= 2;
            }
            for (i_loop = 1; i_loop < u16_dec_len; i_loop++)
            {
                snprintf(p_value_tmp, ui_len_tmp, "%02d", p_dec_data[i_loop]);
                p_value_tmp += 2;
                ui_len_tmp -= 2;
            }
            break;

       /* 负数 */
       case 0x30:
            i_dec_scale = 16 - i_dec_scale;
            /* 申请足够长的内存 */
            ui_len_tmp = (ui_size + 4) * 2;
            p_value = (char *)frmalloc(ui_len_tmp);
            if (p_value == NULL)
            {
                frfree(p_dec_data);
                return APM_L7_ANALYZE_FAIL;
            }
            p_value_tmp = p_value;
            snprintf(p_value_tmp, ui_len_tmp, "-");
            p_value_tmp += 1;
            ui_len_tmp -= 1;
            for (i_loop = 1; i_loop < u16_dec_len; i_loop++)
            {
                if (i_loop == u16_dec_len - 1)
                {
                    i_tmp = 100;
                }
                if (i_loop == i_dec_scale)
                {
                    if (i_dec_scale == 1)
                    {
                        snprintf(p_value_tmp, ui_len_tmp, "0");
                        p_value_tmp += 1;
                        ui_len_tmp -= 1;
                    }
                    snprintf(p_value_tmp, ui_len_tmp, ".%02d"
                             , i_tmp - p_dec_data[i_loop]);
                    p_value_tmp += 3;
                    ui_len_tmp -= 3;

                }
                else
                {
                    if (i_loop == 1)
                    {
                        snprintf(p_value_tmp, ui_len_tmp, "%d"
                                 , i_tmp - p_dec_data[i_loop]);
                        p_value_tmp += strlen(p_value_tmp);
                        ui_len_tmp -= strlen(p_value_tmp);
                    }
                    else
                    {
                        snprintf(p_value_tmp, ui_len_tmp, "%02d"
                                 , i_tmp - p_dec_data[i_loop]);
                        p_value_tmp += 2;
                        ui_len_tmp -= 2;
                    }
                }
            }
            break;

       /* 负数 */
       case 0x40:
            i_dec_scale += 1;
            /* 申请足够长的内存 */
            ui_len_tmp = (ui_size + i_dec_scale + 4) * 2;
            p_value = (char *)frmalloc(ui_len_tmp);
            if (p_value == NULL)
            {
                frfree(p_dec_data);
                return APM_L7_ANALYZE_FAIL;
            }
            p_value_tmp = p_value;
            snprintf(p_value_tmp, ui_len_tmp, "-0.");
            p_value_tmp += 3;
            ui_len_tmp -= 3;
            while (i_dec_scale--)
            {
                snprintf(p_value_tmp, ui_len_tmp, "00");
                p_value_tmp += 2;
                ui_len_tmp -= 2;
            }
            for (i_loop = 1; i_loop < u16_dec_len; i_loop++)
            {
                i_tmp = 100;
                snprintf(p_value_tmp, ui_len_tmp, "%02d"
                        , i_tmp - p_dec_data[i_loop]);
                p_value_tmp += 2;
                ui_len_tmp -= 2;
            }
            break;

       default:
           frfree(p_dec_data);
           return APM_L7_ANALYZE_FAIL;
    }

    frfree(p_dec_data);
    /* 做成Frdata_field */
    i_ret = frtds_create_param(p_value, FRSTRING, pp_st_value);
    if (i_ret != APM_L7_ANALYZE_SUCC)
    {
        frfree(p_value);
        return APM_L7_ANALYZE_FAIL;
    }
    return APM_L7_ANALYZE_SUCC;
}

/*******************************************************************************
*  FUNC     :  解析informix的大类型
*  ARGS     :  p_st_data(入力bytebuff)
*           :  i_null_flg(是否是NULL)
*           :  p_value(大数据替代值)
*           :  pp_st_value(出力数据)
*  RTN      :  APM_L7_ANALYZE_FAIL      (FAIL)
*              APM_L7_ANALYZE_TODO      (NEED MORE DATA)
*              APM_L7_ANALYZE_SUCC      (SUCC)
*  NOTE     :  p_st_data肯定不为NULL
*******************************************************************************/
int informix_convert_to_large(Frbyte_Packet *p_st_data
                             , int i_null_flg
                             , char *p_value
                             , Frdata_field **pp_st_value)
{
    int i_ret = APM_L7_ANALYZE_SUCC;

    if (i_null_flg != 0)
    {
        i_ret = frtds_create_param(NULL, FRSTRING, pp_st_value);
        return i_ret;
    }

    //跳过blob描述
    if (bytebuff_remaining(p_st_data) < 56)
    {
        return APM_L7_ANALYZE_TODO;
    }
    bytebuff_skip(p_st_data, 56);
    i_ret = frtds_create_param(p_value, FRSTRING, pp_st_value);
    return i_ret;
}

/*******************************************************************************
*  FUNC     :  解析informix的大类型
*  ARGS     :  p_st_data(入力bytebuff)
*           :  i_null_flg(是否是NULL)
*           :  pp_st_value(出力数据)
*  RTN      :  APM_L7_ANALYZE_FAIL      (FAIL)
*              APM_L7_ANALYZE_TODO      (NEED MORE DATA)
*              APM_L7_ANALYZE_SUCC      (SUCC)
*  NOTE     :  p_st_data肯定不为NULL
*******************************************************************************/
int informix_convert_to_lob(Frbyte_Packet *p_st_data
                           , int i_null_flg
                           , Frdata_field **pp_st_value)
{
    int i_ret = APM_L7_ANALYZE_SUCC;
    uint32_t u32_len = 0;

    if (i_null_flg != 0)
    {
        i_ret = frtds_create_param(NULL, FRSTRING, pp_st_value);
        return i_ret;
    }

    //跳过blob描述
    if (bytebuff_remaining(p_st_data) < 4)
    {
        return APM_L7_ANALYZE_TODO;
    }
    i_ret = bytebuff_get_int(p_st_data, 4, &u32_len, BYTE_BIG_ENDIAN);
    if (i_ret != FR_SUCC)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    if (u32_len > (unsigned int)bytebuff_remaining(p_st_data))
    {
        return APM_L7_ANALYZE_TODO;
    }
    bytebuff_skip(p_st_data, u32_len);
    i_ret = frtds_create_param(frstrdup("BLOB/CLOB"), FRSTRING, pp_st_value);
    return i_ret;
}
